package cn.com.xy.sms.util;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.json.JSONObject;

import android.content.ContentValues;
import android.content.Context;
import android.os.Process;
import cn.com.xy.sms.sdk.Iservice.OnlineUpdateCycleConfigInterface;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.base.BaseManager;
import cn.com.xy.sms.sdk.db.entity.MatchCacheManager;
import cn.com.xy.sms.sdk.dex.DexUtil;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.util.SigntureUtil;
import cn.com.xy.sms.sdk.queue.RichBubbleTaskQueue;
import cn.com.xy.sms.sdk.smsmessage.BusinessSmsMessage;
import cn.com.xy.sms.sdk.util.JsonUtil;
import cn.com.xy.sms.sdk.util.SdkCache;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;
/*SDK-616 hewengao 20160912 start*/
import cn.com.xy.sms.sdk.threadpool.SmartSmsThreadPoolManager;
/*SDK-616 hewengao 20160912 end*/
public class ParseRichBubbleManager {

    public static boolean isBusy = false;
 
    static long CACHETIME = 21600000L;// 6个小时
    static long CACHETIME_15_DAY = 1296000000;// 15天
//    static ExecutorService richPool = Executors.newFixedThreadPool(1);

    public static void loadBubbleDataByPhoneNum(String phoneNum) {
        // async thread load data
    	SdkCache sdkCache =	SdkCache.createSdkCache(phoneNum);
        synchronized (sdkCache.effectiveRichBubbleData) {
            clearCacheBubbleData(phoneNum);
            phoneNum = StringUtils.getPhoneNumberNo86(phoneNum);
            String where = "phoneNum=?";
            String args[] = new String[] { phoneNum };
            Map<String, JSONObject>  richBubbleData = MatchCacheManager.loadDataByParam(where, args);
            SdkCache.putCacheRichBubbleData(phoneNum, richBubbleData);
        }
    }

    public static void addEffectiveBubbleData(String phoneNum,String msgId,JSONObject data) {
        if (data == null) {
        	return;
        }
    	SdkCache sdkCache =  SdkCache.getSdkCache(phoneNum);
    	if(sdkCache == null){
    		return;
    	}
        synchronized (sdkCache.effectiveRichBubbleData) {
        	sdkCache.effectiveRichBubbleData.put(msgId, data);
        	try{
            	if(data.has("msg_num_md5")){
            		data.remove("msg_num_md5");
            	}
        	}catch(Throwable e){
//        		e.printStackTrace();
                LogManager.e(Constant.TAG, "addEffectiveBubbleData: ", e);

        	}
        }
        synchronized (sdkCache.cacheRichBubbleData) {
        	sdkCache.cacheRichBubbleData.remove(msgId);
        }
        synchronized (sdkCache.invalidRichBubbleData) {
        	sdkCache.invalidRichBubbleData.remove(msgId);
        }
        synchronized (sdkCache.inQueueRichBubbleData) {
        	sdkCache.inQueueRichBubbleData.remove(msgId);
        }

        try{
            data.remove("viewPartParam");
        }catch(Throwable e){
//            e.printStackTrace();
            LogManager.e(Constant.TAG, "addEffectiveBubbleData: ", e);

        }
        
    }
    public static void addInvalidBubbleData(String phoneNum,String msgId) {
        if (msgId != null) {
        	return;
        }
    	SdkCache sdkCache =  SdkCache.getSdkCache(phoneNum);
    	if(sdkCache == null){
    		return;
    	}
        synchronized (sdkCache.invalidRichBubbleData) {
        	sdkCache.invalidRichBubbleData.add(msgId);
        }
        synchronized (sdkCache.cacheRichBubbleData) {
        	sdkCache.cacheRichBubbleData.remove(msgId);
        }
        synchronized (sdkCache.effectiveRichBubbleData) {
        	sdkCache.effectiveRichBubbleData.remove(msgId);
        }
        synchronized (sdkCache.inQueueRichBubbleData) {
        	sdkCache.inQueueRichBubbleData.remove(msgId);
        }
        
    }
    public static void pubBubbleData(String phone,Map<String, JSONObject> data,boolean clearPrev) {
    	SdkCache sdkCache =	SdkCache.createSdkCache(phone);
        synchronized (sdkCache.cacheRichBubbleData) {
            if(clearPrev){
            	sdkCache.clearSdkRichCache();
            }
            if (data != null) {
                sdkCache.cacheRichBubbleData.putAll(data);
                /* SDK-559 huangzhiqiang 20160725 start */
                LogManager.d("duoqu_xiaoyuan", "pubBubbleData data size: ", String.valueOf(data.size()));
                /* SDK-559 huangzhiqiang 20160725 end */
            }else{
                /* SDK-559 huangzhiqiang 20160725 start */
                LogManager.d("duoqu_xiaoyuan", "pubBubbleData data size is null ",null);
                /* SDK-559 huangzhiqiang 20160725 end */
            }
        }
    }

    public static void clearCacheBubbleData(String phoneNum) {
    	SdkCache.delSdkCache(phoneNum);
        BusinessSmsMessage.emptyObj =null;
    }

    public static JSONObject queryDataByMsgItem(String msgId, String phoneNum,
            String smsContent, String centerNum, int dataType,long smsReceiveTime) throws Exception {
        if (msgId == null || phoneNum == null || smsContent == null) {
            throw new Exception(
                    "msgid or phoneNum or smsContent is null but they need value.");
        }
        if (StringUtils.isPhoneNumber(phoneNum))
            return null;
        JSONObject res = null;
        SdkCache sdkCache =	SdkCache.createSdkCache(phoneNum);
        if (sdkCache.effectiveRichBubbleData != null) {
            res = sdkCache.effectiveRichBubbleData.get(msgId);
            if (res != null) {
                return res;
            }
        }
        if (res == null && sdkCache.invalidRichBubbleData.contains(msgId)) {
            return null;
        }
        int dataStatu = 0;
        if (res == null && sdkCache.cacheRichBubbleData != null) {
            res = sdkCache.cacheRichBubbleData.get(msgId);
            if (res != null) {
                String md5 = (String) JsonUtil.getValueFromJsonObject(res,
                        "msg_num_md5");
                String md5_1 = MatchCacheManager.getMD5(phoneNum, smsContent);

//                PrintTestLogUtil.printTestLog("queryDataByMsgItem", "md5="
//                        + md5 + " md5_1=" + md5_1);
                if (md5_1 != null && md5 != null && md5_1.equals(md5)) {

                    if (dataType == 2) {
                        String data = (String) JsonUtil.getValueFromJsonObject(
                                res, "bubble_result");

//                        PrintTestLogUtil.printTestLog("queryDataByMsgItem",
//                                "data=" + data);

                        try {
                            long lastTime = Long.valueOf(JsonUtil
                                    .getValueFromJsonObject(res,
                                            "bubble_lasttime").toString());
                            if (!StringUtils.isNull(data)) {
                                if (System.currentTimeMillis() - lastTime < (DexUtil.getUpdateCycleByType(
                                        OnlineUpdateCycleConfigInterface.TYPE_REPARSE_CYCLE, CACHETIME_15_DAY))) {// 已识别的丰富气泡，没有超过15天有效期,不需要重新走识别流程
                                    JSONObject dataArr = new JSONObject(data);
                                    sdkCache.effectiveRichBubbleData.put(msgId, dataArr);
                                    dataStatu = 1;
                                }
                            } else {

                                if (System.currentTimeMillis() - lastTime < DexUtil.getUpdateCycleByType(
                                        OnlineUpdateCycleConfigInterface.TYPE_PARSE_FAIL_REPARSE_CYCLE, CACHETIME)) {// 不识别的丰富气泡超过6小时后重新走识别流程
                                    sdkCache.invalidRichBubbleData.add(msgId);// invalid data
                                    dataStatu = 2;
                                }
                            }
                        } catch (Throwable e) {
//                            e.printStackTrace();
                            LogManager.e(Constant.TAG, "queryDataByMsgItem: ", e);

                            sdkCache.invalidRichBubbleData.add(msgId);// invalid data
                            dataStatu = 2;

                        }
                    }
                } else {
                    // find cache but data is not same
                    // invalidBubbleData.add(msgId);
                    dataStatu = 3;
                    sdkCache.invalidRichBubbleData.remove(msgId);
                }
                sdkCache.cacheRichBubbleData.remove(msgId);
            }
        }
        // /if(dataStatu == 0){

        // }
        if (dataStatu != 1) {
            if (sdkCache.inQueueRichBubbleData.contains(msgId)) {
                return null;
            } else {
            	sdkCache.inQueueRichBubbleData.add(msgId);
            }
            // 加入后台队列处理
            RichBubbleTaskQueue.addDataToQueue(dataStatu, msgId, phoneNum,
                    smsContent, centerNum, dataType,smsReceiveTime, res);
        }
        return res;
    }

    public static void queryDataByMsgItem(final String msgId,
            final String phoneNum, final String smsContent,final long smsReceiveTime,
            final String centerNum, final int dataType,
            final SdkCallBack xyCallBack, boolean scrollFing,final HashMap<String, Object> extend) throws Exception {
        if (msgId == null || phoneNum == null || smsContent == null) {
            throw new Exception(
                    "msgid or phoneNum or smsContent is null but they need value.");
        }
//        LogManager.d("duoqu_xiaoyuan", "queryDataByMsgItem: msgId: "+msgId);
//        PrintTestLogUtil.printTestLog("queryDataByMsgItem", "1 start: ");
        if (StringUtils.isPhoneNumber(phoneNum)) {
            XyUtil.doXycallBackResult(xyCallBack, -1, "phonenum is null",
                    msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
            return;
        }
        JSONObject res = null;
        /*SDK-720 songzhirong 20170117 start */
        boolean tempIsFavorite = false;
        if (extend != null
                && Constant.FAVORITE_TYPE_SMS.equalsIgnoreCase((String) extend.get(Constant.IS_FAVORITE))) {
        	tempIsFavorite = true;
        }        
        final boolean isFavorite = tempIsFavorite;
        /*SDK-720 songzhirong 20170117 end */
        
        final SdkCache sdkCache =	SdkCache.createSdkCache(phoneNum);
        if (sdkCache.effectiveRichBubbleData != null) {
            res = sdkCache.effectiveRichBubbleData.get(msgId);
            if (res != null) {
                XyUtil.doXycallBackResult(xyCallBack, 0, res, msgId,
                        ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                /*SDK-720 songzhirong 20170117 start */               
                addToFavorite(msgId, phoneNum, smsContent, smsReceiveTime, isFavorite, res);
                /*SDK-720 songzhirong 20170117 end */
                return;
            }

        }
//        PrintTestLogUtil.printTestLog("queryDataByMsgItem", "2 start: ");
        if (res == null && sdkCache.invalidRichBubbleData.contains(msgId)) {
            XyUtil.doXycallBackResult(xyCallBack, -1, msgId+ " invalidBubbleData ",
                    msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
            return;
        }
//        PrintTestLogUtil.printTestLog("queryDataByMsgItem", "3 start: ");
        int dataStatu = 0;
        if (res == null && sdkCache.cacheRichBubbleData != null) {
            res = sdkCache.cacheRichBubbleData.get(msgId);
            if (res != null && !res.has("need_parse_bubble")) {
                /*SDK-720 songzhirong 20170117 start */
            	addToFavorite(msgId, phoneNum, smsContent, smsReceiveTime, isFavorite, res);
                /*SDK-720 songzhirong 20170117 end */
                dataStatu =3;
                String md5 = (String) JsonUtil.getValueFromJsonObject(res,"msg_num_md5");
                String md5_1 = MatchCacheManager.getMD5(phoneNum, smsContent);
                if (md5_1 != null && md5 != null && md5_1.equals(md5)) {

                    if (dataType == 2) {
 
                        try {
                            JSONObject dataArr = (JSONObject) JsonUtil.getValueFromJsonObject(res, "bubble_result");
                            if(dataArr != null){
                            	sdkCache.effectiveRichBubbleData.put(msgId, dataArr);
                                dataStatu = 1;
                                XyUtil.doXycallBackResult(xyCallBack, 0,dataArr,
                                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                                return;
                            }else{
                            	sdkCache.invalidRichBubbleData.add(msgId);// invalid data
                                    dataStatu = 2;
                            }
                        } catch (Throwable e) {
//                            e.printStackTrace();
                            LogManager.e(Constant.TAG, "queryDataByMsgItem: ", e);

//                            LogManager.e("duoqu_xiaoyuan", "error add  invalidBubbleData msgId:  "+msgId+" "+e.getMessage());
                            sdkCache.invalidRichBubbleData.add(msgId);// invalid data
                            dataStatu = 2;

                        }
                    }
                } else {
                    // find cache but data is not same
                    // invalidBubbleData.add(msgId);
                    dataStatu = 3;
                }
                sdkCache.cacheRichBubbleData.remove(msgId);
            }
        }
//        LogManager.d("duoqu_xiaoyuan", "queryDataByMsgItem: msgId: "+msgId +"  dataStatu: "+dataStatu);
        if (dataStatu == 0 || dataStatu ==3) {
            if (sdkCache.inQueueRichBubbleData.contains(msgId)) {
                XyUtil.doXycallBackResult(xyCallBack, -1, " inQueueBubbleData2 ",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                return;
            } else {
//                sdkCache.inQueueRichBubbleData.add(msgId);
            }
            if (!scrollFing) {
                /* SDK-591 huangzhiqiang 20160815 start */
                sdkCache.inQueueRichBubbleData.add(msgId);
                /* SDK-591 huangzhiqiang 20160815 end */
                XyUtil.doXycallBackResult(xyCallBack, -2, " need parse ",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                final int dataStatuTemp = dataStatu;
                /*SDK-616 hewengao 20160912 start*/
                SmartSmsThreadPoolManager.richPool.execute(new Runnable() {
                /*SDK-616 hewengao 20160912 end*/
                    public void run() {
                        try {
                            /*SDK-616 hewengao 20160912 start*/
                            SmartSmsThreadPoolManager.setThreadNameAndPriority(SmartSmsThreadPoolManager.TNAME_RICHPOOL,
                                    Process.THREAD_PRIORITY_BACKGROUND);
                            /*SDK-616 hewengao 20160912 end*/
                            JSONObject dataArr =  null;
                            JSONObject res= null;
                            if(dataStatuTemp == 0){
                                //from db query
                                res=queryBubbleDataFromDb(msgId,phoneNum,smsContent,smsReceiveTime);
                                if(res != null && !res.has("need_parse_bubble")){
                                	
                                    dataArr = (JSONObject) JsonUtil.getValueFromJsonObject(res, "bubble_result");
                                    if(dataArr != null){
                                        synchronized (sdkCache.effectiveRichBubbleData) {
                                            sdkCache.effectiveRichBubbleData.put(msgId, dataArr);
                                        }
                                        sdkCache.cacheRichBubbleData.remove(msgId);
                                        sdkCache.invalidRichBubbleData.remove(msgId);
                                        XyUtil.doXycallBackResult(xyCallBack, 1, dataArr,
                                                msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                                        /*SDK-720 songzhirong 20170117 start */
                                        addToFavorite(msgId, phoneNum, smsContent, smsReceiveTime, isFavorite, res);
                                        /*SDK-720 songzhirong 20170117 end */
                                        return;
                                    }else{
                                        sdkCache.invalidRichBubbleData.add(msgId);// invalid data
                                        sdkCache.cacheRichBubbleData.remove(msgId);
                                        XyUtil.doXycallBackResult(xyCallBack, -3," invalid data ",
                                                msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                                        /*SDK-720 songzhirong 20170117 start */
                                        addToFavorite(msgId, phoneNum, smsContent, smsReceiveTime, isFavorite, res);
                                        /*SDK-720 songzhirong 20170117 end */
                                        return;
                                    }
                                }
                            }
                            if(dataArr == null){
                                /*SDK-720 songzhirong 20170117 start */
                                if(!isFavorite){
                                	  //from parse api
                                    dataArr=queryBubbleDataFromApi(msgId,phoneNum,smsContent,centerNum,smsReceiveTime,extend);
                                }  
                                /*SDK-720 songzhirong 20170117 end */
                                if(dataArr != null){
                                        synchronized (sdkCache.effectiveRichBubbleData) {
                                            sdkCache.effectiveRichBubbleData.put(msgId, dataArr);
                                        }
                                        sdkCache.invalidRichBubbleData.remove(msgId);
                                        sdkCache.cacheRichBubbleData.remove(msgId);
                                        XyUtil.doXycallBackResult(xyCallBack, 1, dataArr,
                                                msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                                }else{
                                    sdkCache.invalidRichBubbleData.add(msgId);
                                    sdkCache.cacheRichBubbleData.remove(msgId);
                                    LogManager.d("duoqu_xiaoyuan", "add  invalidBubbleData msgId:  ",msgId);
                                    XyUtil.doXycallBackResult(xyCallBack, -3, " parse failed ",
                                            msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
                                }
                            }
                            //LogManager.d("duoqu_xiaoyuan", "  $$$$$ queryDataByMsgItem: msgId: "+msgId);
                        }catch(Throwable e){
                            XyUtil.doXycallBackResult(xyCallBack, -3, "error: "+e.getLocalizedMessage(),
                                    msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
//                            e.printStackTrace();
                            LogManager.e(Constant.TAG, "queryDataByMsgItem: ", e);

                        }finally{
                            sdkCache.inQueueRichBubbleData.remove(msgId);
                        }
                    }
                });
            } else {
                XyUtil.doXycallBackResult(xyCallBack, -4, " is scrolling",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
            }
        }else{
        	  XyUtil.doXycallBackResult(xyCallBack, -1, " invalidBubbleData dataStatu: "+dataStatu,
        	          msgId,  ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG);
        	   /*SDK-720 songzhirong 20170117 start */
        	  addToFavorite(msgId, phoneNum, smsContent, smsReceiveTime, isFavorite, res);
        	    /*SDK-720 songzhirong 20170117 end */
        }
    }
    /*SDK-720 songzhirong 20170117 start */
	public static void addToFavorite(final String msgId, final String phoneNum,
			final String smsContent, final long smsReceiveTime,
			boolean isFavorite, JSONObject res) {
		try {
			if (isFavorite && res != null
					&& !Constant.IS_MARK.equalsIgnoreCase(res.optString("is_mark"))) {
				res.put("is_mark", Constant.IS_MARK);
				res.put("is_favorite", Constant.FAVORITE_TYPE_SMS);
				ParseFavoriteManager.addToFavorite(msgId, phoneNum, smsContent,
						smsReceiveTime, null);
			}
		} catch (Throwable e) {
			// TODO: handle exception
		}
		
	}
    /*SDK-720 songzhirong 20170117 end */   
    
    public static JSONObject queryBubbleDataFromDb(String msgId,String phoneNum,String smsContent,long smsReceiveTime){
        JSONObject res = null;
        //from db query
        res = MatchCacheManager.getDataByParam(msgId);
        if(res != null){
            String md5 = (String) JsonUtil.getValueFromJsonObject(res,"msg_num_md5");
            String md5_1 = MatchCacheManager.getMD5(phoneNum,smsContent);
            if(null != md5 && md5.equals(md5_1)){
                return res;
            }
        }
        return null;
    }
    public static JSONObject queryBubbleDataFromApi(String msgId,String phoneNum,String smsContent,String centerNum,long smsReceiveTime,final HashMap<String, Object> extend){
                    Map<String,Object> obj= ParseSmsToBubbleUtil.parseSmsToBubbleResult(msgId,
                                      phoneNum,smsContent,centerNum,
                                      smsReceiveTime,3,true,true,extend); 

                    if(obj != null){
                        return (JSONObject)obj.get("BUBBLE_JSON_RESULT");
                    }
                    return null;

    }
    
    /**
     * 解析短信并返回解析结果,结果用于短信会话列表创建简单汽泡视图
     * 
     * @param ctx
     *            上下文
     * @param msgId
     *            短消息ID
     * @param phoneNumber
     *            短信接入码,短信发送方号码
     * @param smsCenterNum
     *            短信发送方,短信中心号码
     * @param smsContent
     *            短信内容
     * @param returnCacheType
     *            返回数据的缓存类型 1:返回SDK缓存标识 2:返回SDK识别结果 由开发者保存sdk标识或识别结果.
     * @param extend
     *            Map<String, String>
     * @return Map<String, Object> 包含key CACHE_SDK_MSG_ID 识别结果标识ID
     *         CACHE_SDK_MSG_RESULT:识别结果 value:jsonstring
     * 
     */
    public static Map<String, Object> parseMsgToSimpleBubbleResult(Context ctx,
            String msgId, String phoneNumber, String smsCenterNum,
            String smsContent, byte returnCacheType, Map<String, String> extend)
            throws Exception {
        if (!SigntureUtil
                .checkChannelFuncPower(Constant.POWER_TOSIMPLEBUBBLE_VIEW))
            return null;
        String data = ParseManager.parseMsgToBubble(ctx, phoneNumber,
                smsCenterNum, smsContent, extend);
        Map<String, Object> res = null;
        if (returnCacheType == 1) {// xiao yuan sdk persistent simple bubble
                                   // data
            long sdkMsgId = 0;
            String msg_num_md5 = MatchCacheManager.getMD5(phoneNumber,
                    smsContent);
            if (!StringUtils.isNull(msg_num_md5)) {

                ContentValues matchCache = BaseManager.getContentValues(null,
                        "msg_num_md5", msg_num_md5, "phonenum",
                        StringUtils.getPhoneNumberNo86(phoneNumber), "msg_id",
                        msgId, "session_reuslt", data == null ? "" : data,
                        "save_time", String.valueOf(System.currentTimeMillis()),
                        "session_lasttime",String.valueOf(System.currentTimeMillis())
                		);
                sdkMsgId = MatchCacheManager.insertOrUpdate(matchCache, 1);
            }
            if (data != null) {
                res = new HashMap<String, Object>();
                res.put("CACHE_SDK_MSG_ID", sdkMsgId);
                res.put("CACHE_SDK_MSG_RESULT", data);
            }
        } else {
            if (data != null) {
                res = new HashMap<String, Object>();
                res.put("CACHE_SDK_MSG_RESULT", data);
            }
        }
        return res;
    }

    public static void deleteBubbleDataFromCache(String phone, String msgId) {
        try {
            if (StringUtils.isNull(phone)) {
                SdkCache.clearAllSdkCache(msgId);
            }
            SdkCache sdkCache = SdkCache.getSdkCache(phone);
            if (sdkCache != null) {
                sdkCache.clearSdkCache(msgId);
            }
        } catch (Throwable e) {
        }
    }

    /* SDK-591 huangzhiqiang 20160815 start */
    public static void deleteParseDataFromCache(String msgId){
        try {
            SdkCache.clearAllParseDataCache(msgId);
        } catch (Throwable e) {
        }
    }
    /* SDK-591 huangzhiqiang 20160815 end */
}
